3D Graphics Programming with QuickDraw 3D 1.5.4
Previous | QD3D Book | Overview | Chapter Contents | Next |
You can iterate through a group by getting the position of its first object and then getting the positions of any subsequent objects. All groups, regardless of type, are stored in a single list which you can step through only by calling QuickDraw 3D routines.
Listing 2 shows how to access all the lights in a light group. The MyTurnOnOrOffAllLights function takes a view parameter and an on/off state value. It turns all the lights in the view's light group on or off, as specified by the state value.
Listing 2 Accessing all the lights in a light group
TQ3Status MyTurnOnOrOffViewLights (TQ3ViewObject myView, TQ3Boolean myState)
{
TQ3GroupObject myGroup; /*the view's light group*/
TQ3GroupPosition myPos; /*a group position*/
TQ3Object myLight; /*a light*/
TQ3Status myResult; /*a result code*/
myResult = Q3View_GetLightGroup(myView, &myGroup);
if (myResult == kQ3Failure)
goto bail;
for (Q3Group_GetFirstPosition(myGroup, &myPos);
myPos != NULL;
Q3Group_GetNextPosition(myGroup, &myPos))
{
myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight);
if (myResult == kQ3Failure)
goto bail;
myResult = Q3Light_SetState(myLight, myState);
Q3Object_Dispose(myLight); /*balance reference count of light*/
}
return(kQ3Success);
bail:
return(kQ3Failure);
}
You can use the looping technique illustrated in Listing 2 to traverse ordered display groups as well, as shown in Listing 3 . The function MyToggleOrderedGroupLights traverses an ordered display group and toggles any lights it finds. Notice that MyToggleOrderedGroupLights calls the Q3Group_GetFirstPositionOfType function to find the position of the first light in the group.
Listing 3 Accessing all the lights in an ordered display group
TQ3Status MyToggleOrderedGroupLights (TQ3GroupObject myGroup)
{
TQ3GroupPosition myPos; /*a group position*/
TQ3Object myLight; /*a light*/
TQ3Boolean myState; /*a light state*/
TQ3Status myResult; /*a result code*/
for (Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos);
myPos != NULL;
Q3Group_GetNextPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos))
{
myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight);
if (myResult == kQ3Failure)
goto bail;
myResult = Q3Light_GetState(myLight, &myState);
myState = !myState; /*toggle the light state*/
myResult = Q3Light_SetState(myLight, myState);
Q3Object_Dispose(myLight); /*balance reference count of light*/
}
return(kQ3Success);
bail:
return(kQ3Failure);
}
It's also possible to find the position of the next object in an ordered display group by calling the Q3Group_GetNextPosition function. Q3Group_GetNextPosition is not, however, guaranteed to return a position of an object that is of the same type as the object immediately before it. If you use Q3Group_GetNextPosition to iterate through an ordered display group, you must therefore make sure not to step past the part of the list that contains objects of the type you're interested in. Listing 4 shows, in outline, how to call Q3Group_GetNextPosition to iterate safely through an object type in an ordered display group.
Listing 4 Accessing all the lights in an ordered display group using Q3Group_GetNextPosition
TQ3GroupPosition myFirst; /*group position of first light*/
TQ3GroupPosition myLast; /*group position of last light*/
TQ3Object myLight; /*a light*/
TQ3Status myResult; /*a result code*/
Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myFirst);
if (myFirst) {
Q3Group_GetLastPositionOfType(myGroup, kQ3ShapeTypeLight, &myLast);
do
{
myResult = Q3Group_GetPositionObject(myGroup, myFirst, myLight);
if (myResult == kQ3Failure)
goto bail;
myResult = Q3Light_GetState(myLight, &myState);
myState = !myState; /*toggle the light state*/
myResult = Q3Light_SetState(myLight, myState);
Q3Object_Dispose(myLight); /*balance reference count of light*/
Q3Group_GetNextPosition(myGroup, &myFirst);
} while (myFirst != myLast);
}
Previous | QD3D Book | Overview | Chapter Contents | Next |